package com.vhall.component.framework.common.utils;

import com.vhall.component.framework.common.constant.CommonConstant;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 功能：分析导入的url并进行分解，转换成标准URL对象
 * <p>
 * 2021年5月6日
 */
@Slf4j
@Getter
public final class URLParser {

    private static final Pattern PROTOCOL_SPLIT = Pattern.compile("(.*?)://(.*)");
    private static final Pattern SLASH_SPLIT = Pattern.compile("(.*?)/(.*)");
    private static final Pattern HOST_PORT_SPLIT = Pattern.compile("(.*?)\\:(\\d*)");

    private String protocol;

    private String host;

    private int port;

    private String path;

    public static URLParser create(String url) {
        URLParser parser = new URLParser();

        // parse protocol
        String protocol = null;
        Matcher m = PROTOCOL_SPLIT.matcher(url);
        String remainder;
        String u = url.toString();
        if (m.find()) {
            protocol = m.group(1);
            remainder = m.group(2);
        } else {
            remainder = u;
        }
        if (protocol != null && protocol.trim().length() == 0) {
            protocol = null;
        }

        parser.protocol = protocol;

        // parse host
        String host = null;
        if (host == null) {
            m = SLASH_SPLIT.matcher(remainder);
            if (m.find()) {
                host = m.group(1);
                remainder = m.group(2);
            } else {
                host = remainder;
                remainder = null;
            }
        }

        // parse port
        int port = -1;
        m = HOST_PORT_SPLIT.matcher(host);
        if (m.lookingAt()) {
            host = m.group(1);
            if (m.groupCount() > 1) {
                port = Short.valueOf(m.group(2));
            } else {
                port = -1;
            }
        }

        parser.host = host;
        parser.port = port;
        parser.path = StringUtils.isNotEmpty(remainder) ? "/".concat(remainder) : null;

        return parser;
    }

    /**
     * 获取主机
     *
     * @return
     */
    public String hostname() {
        return StringUtils.isNotEmpty(host) ?
                host.concat(":").concat(String.valueOf(port))
                : null;
    }

    /**
     * 获取源域
     *
     * @return
     */
    public String origin() {
        StringBuilder result = new StringBuilder(protocol).append("://").append(host);
        if (port != -1) {
            result.append(":").append(port != -1 ? port : "");
        }
        return result.toString();
    }

    /**
     * @param url
     * @return
     */
    public static String encodeUrl(String url) {
        try {
            return URLEncoder.encode(url, CommonConstant.UTF8);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }
        return null;
    }

    /**
     * @param url
     * @return
     */
    public static String decodeUrl(String url) {
        try {
            return URLDecoder.decode(url, CommonConstant.UTF8);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }
        return null;
    }


}
